package com.um.jdy.common.alarm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.um.jdy.common.alarm.entity.po.AlarmCode;
import com.um.jdy.common.alarm.entity.po.AlarmNotice;
import com.um.jdy.common.alarm.entity.po.AlarmRule;
import com.um.jdy.common.alarm.enums.AlarmEnum;
import com.um.jdy.common.alarm.service.AlarmCodeService;
import com.um.jdy.common.alarm.service.AlarmNoticeService;
import com.um.jdy.common.alarm.service.AlarmRuleService;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.device.entity.po.Gun;
import com.um.jdy.common.device.entity.po.Pile;
import com.um.jdy.common.device.entity.po.Station;
import com.um.jdy.common.device.service.GunService;
import com.um.jdy.common.device.service.PileService;
import com.um.jdy.common.device.service.StationService;
import com.um.jdy.common.platform.entity.po.Merchant;
import com.um.jdy.common.platform.entity.po.Notification;
import com.um.jdy.common.platform.service.MerchantService;
import com.um.jdy.common.platform.service.NotificationService;
import com.um.jdy.common.push.service.PushService;
import com.um.jdy.common.system.service.UserService;
import com.um.springboot.starter.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import com.um.springboot.starter.orm.service.BaseEntityServiceImpl;
import com.um.jdy.common.alarm.service.AlarmRecordService;
import com.um.jdy.common.alarm.dao.AlarmRecordDao;
import com.um.jdy.common.alarm.entity.po.AlarmRecord;

import java.util.ArrayList;
import java.util.List;

/**
 * 服务实现类：告警记录表
 */
@Service
@Transactional
@Slf4j
public class AlarmRecordServiceImpl extends BaseEntityServiceImpl<AlarmRecordDao, AlarmRecord>  implements AlarmRecordService {

    @Autowired
    NotificationService notificationService;

    @Autowired
    GunService gunService;

    @Autowired
    PileService pileService;

    @Autowired
    StationService stationService;

    @Autowired
    AlarmCodeService alarmCodeService;

    @Autowired
    AlarmRuleService alarmRuleService;

    @Autowired
    AlarmNoticeService alarmNoticeService;

    @Autowired
    AlarmRecordService alarmRecordService;

    @Autowired
    MerchantService merchantService;

    @Autowired
    UserService userService;

    @Autowired
    PushService pushService;

    public void add(String deviceStationId, String devicePileId, String deviceGunId, String errorCode, String remark) {
        // 半小时内重复错误代码只记录一次
        AlarmRecord alarmRecord = alarmRecordService.getEntityBySqlName("get_30m_faulted",
                new String[]{devicePileId, deviceGunId, errorCode});
        if(null != alarmRecord){
            return;
        }

        Gun gun = gunService.getRow(deviceGunId);

        alarmRecord = new AlarmRecord();
        alarmRecord.setComId(gun.getComId());
        alarmRecord.setCreateTime(DateUtil.date());
        alarmRecord.setDevicePileId(devicePileId);
        alarmRecord.setDeviceGunId(deviceGunId);
        alarmRecord.setConnectorId(gun.getPort());
        alarmRecord.setErrorCode(errorCode);
        alarmRecord.setRemark(remark);
        alarmRecord.setAlarmType(AlarmEnum.AlarmType.Alarm.name());
        alarmRecord.setStatus(AlarmEnum.HandStatus.New.name());
        alarmRecordService.saveRow(alarmRecord);

        Station station = stationService.getRow(deviceStationId);

        //告警
        AlarmNotice alarmNotice = new AlarmNotice();
        alarmNotice.setComId(gun.getComId());
        alarmNotice.setDeviceStationId(deviceStationId);
        alarmNotice.setDevicePileId(devicePileId);
        alarmNotice.setDeviceGunId(deviceGunId);
        alarmNotice.setConnectorId(gun.getPort());
        alarmNotice.setAlarmTime(DateUtil.date());
        alarmNotice.setErrorCode(errorCode);

        alarm(alarmNotice, errorCode, station.getPlatformMerchantId());

    }

    /**
     * 告警
     * @param alarmNotice
     * @param errorCode
     * @param platformMerchantId
     */
    public void alarm(AlarmNotice alarmNotice, String errorCode, String platformMerchantId){
        AlarmCode alarmCode = alarmCodeService.getRow("code", errorCode);
        if(null != alarmCode){
            alarmNotice.setLevel(String.valueOf(alarmCode.getLevel()));
        }

        Station station = stationService.getRow(alarmNotice.getDeviceStationId());
        Pile pile = pileService.getRow(alarmNotice.getDevicePileId());
        Gun gun = gunService.getRow(alarmNotice.getDeviceGunId());
        Notification notification = notificationService.getRow("com_id", station.getComId());
        if(null == notification || !YesOrNo.Yes.name().equals(notification.getIsMpEnable())){
            return;
        }

        List<AlarmRule> ruleList = alarmRuleService.getList(new String[]{}, new String[]{});
        ruleList.stream()
                .filter(rule -> StringUtil.getTrim(rule.getCodes()).contains(errorCode) || rule.getCodes().equals("All"))
                .forEach(rule -> {

                    alarmNotice.setNotifyChannel(rule.getNotifyChannel());
                    alarmNotice.setNotifyTarget(rule.getNotifyTarget());

                    //通知渠道
                    switch (AlarmEnum.NotifyType.valueOf(rule.getNotifyChannel())){
                        case MPSms:

                            List<String> openIdList = new ArrayList();

                            //通知目标
                            switch (AlarmEnum.NotifyTarget.valueOf(rule.getNotifyTarget())){
                                case Admin:
                                    openIdList.addAll(JSONUtil.parseArray(notification.getAdminIds()).toList(String.class));
                                    break;

                                case Operator:
                                    Merchant merchant = merchantService.getEntity(platformMerchantId);
                                    if(null == merchant || StrUtil.isBlank(merchant.getMpOpenId())){
                                        break;
                                    }
                                    openIdList.add(merchant.getMpOpenId());
                                    break;
                            }

                            if(openIdList.size() == 0){
                                break;
                            }

                            try {
                                pushService.pushDeviceFault(notification,openIdList, station.getName(), pile.getCode(), gun.getPort(),
                                        errorCode, alarmNotice.getAlarmTime());
                            }catch (Exception e){
                                log.error("发送告警推送错误", e);
                            }

                            alarmNotice.setNotifyAccount(JSONUtil.toJsonStr(openIdList));
                            alarmNoticeService.save(alarmNotice);
                            break;
                    }
                });
    }
}
